package io.zhengsh.vvip.leetcode.binarysearch;

import java.util.concurrent.Semaphore;

class MyThread extends Thread {
    private Semaphore semaphore;

    public MyThread(String name, Semaphore semaphore) {
        super(name);
        this.semaphore = semaphore;
    }

    public void run() {
        int count = 3;
        System.out.println(Thread.currentThread().getName() + " trying to acquire");
        try {
            semaphore.acquire(count);
            System.out.println(Thread.currentThread().getName() + " acquire successfully");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release(count);
            System.out.println(Thread.currentThread().getName() + " release successfully");
        }
    }
}

public class SemaphoreDemo {
    public final static int SEM_SIZE = 10;

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(SEM_SIZE);
        MyThread t1 = new MyThread("t1", semaphore);
        MyThread t2 = new MyThread("t2", semaphore);
        t1.start();
        t2.start();
        int permits = 5;
        System.out.println(Thread.currentThread().getName() + " trying to acquire");
        try {
            semaphore.acquire(permits);
            System.out.println(Thread.currentThread().getName() + " acquire successfully");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
            System.out.println(Thread.currentThread().getName() + " release successfully");
        }
    }

    // 内部类，继承自AQS
    // abstract static class Sync extends AbstractQueuedSynchronizer {         // 版本号         private static final long serialVersionUID = 1192457210091910933L;                  // 构造函数         Sync(int permits) {             // 设置状态数             setState(permits);         }                  // 获取许可         final int getPermits() {             return getState();         }         // 共享模式下非公平策略获取         final int nonfairTryAcquireShared(int acquires) {             for (;;) { // 无限循环                 // 获取许可数                 int available = getState();                 // 剩余的许可                 int remaining = available - acquires;                 if (remaining < 0 ||                     compareAndSetState(available, remaining)) // 许可小于0或者比较并且设置状态成功                     return remaining;             }         }                  // 共享模式下进行释放         protected final boolean tryReleaseShared(int releases) {             for (;;) { // 无限循环                 // 获取许可                 int current = getState();                 // 可用的许可                 int next = current + releases;                 if (next < current) // overflow                     throw new Error("Maximum permit count exceeded");                 if (compareAndSetState(current, next)) // 比较并进行设置成功                     return true;             }         }         // 根据指定的缩减量减小可用许可的数目         final void reducePermits(int reductions) {             for (;;) { // 无限循环                 // 获取许可                 int current = getState();                 // 可用的许可                 int next = current - reductions;                 if (next > current) // underflow                     throw new Error("Permit count underflow");                 if (compareAndSetState(current, next)) // 比较并进行设置成功                     return;             }         }         // 获取并返回立即可用的所有许可         final int drainPermits() {             for (;;) { // 无限循环                 // 获取许可                 int current = getState();                 if (current == 0 || compareAndSetState(current, 0)) // 许可为0或者比较并设置成功                     return current;             }         }     }
}